package services;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import repositories.EvaluationRepository;
import domain.Evaluation;
import domain.Event;
import domain.Participant;
import domain.Route;

@Service
@Transactional
public class EvaluationService {
	
	// Managed repository -----------------------------------------------------
	
				@Autowired
				private EvaluationRepository evaluationRepository;

				@Autowired
				private EventService eventService;
				
				@Autowired
				private ParticipantService participantService;
				
				// Constructors -----------------------------------------------------------

				public EvaluationService() {
					super();
				}
				
				// Simple CRUD methods ----------------------------------------------------
				
				public Evaluation create(Route r){
					Evaluation res = new Evaluation();
					
					Participant p = participantService.findByPrincipal();
					
					//comprobar que el participante este registrado en el evento de la ruta
					Collection<Event> principalEvents = eventService.findEventsByParticipant();
					Event routeEvent = r.getEvent();
					
					Assert.isTrue(principalEvents.contains(routeEvent),"tried to assess to a not registered event");
					
					res.setParticipant(p);
					res.setRoute(r);
					
					return res;
				}
				
				
				public void save(Evaluation e){
					Assert.notNull(e,"tried to save a null evaluation");
					
					checkPrincipal(e,"tried to modify an evaluation property of other participant");
					
					
					this.evaluationRepository.save(e);
				}

				public void delete(Evaluation e){
					Assert.notNull(e,"tried to delete a null evaluation");
					Assert.isTrue(this.evaluationRepository.exists(e.getId()),"tried to delete a non existent evaluation");
					
					checkPrincipal(e,"tried to delete an evaluation property of other participant");
					
					this.evaluationRepository.delete(e);
				}
				
				// Other business methods -------------------------------------------------

				public Evaluation findOne(int id){
					Assert.isTrue(id!=0,"tried to find an evaluation with id zero");
					
					Evaluation res;
					
					res = this.evaluationRepository.findOne(id);
					Assert.notNull(res,"found evaluation is null");
					
					return res;
				}
				
				//listar todas las evaluaciones de una ruta
				public Collection<Evaluation> findAllByRoute(Route r){
					Assert.notNull(r,"tried to find evaluations for a null route");
					Assert.isTrue(r.getId()!=0,"tried to find evaluations for a route with id zero");
					
					Collection<Evaluation> res;
					
					res = this.evaluationRepository.findEvaluationsByRoute(r.getId());
					
					return res;
				}
				
				//listar todas las evaluaciones de un participante
				public Collection<Evaluation> findAllByParticipant(Participant p){
					Assert.notNull(p,"tried to found evaluations made by a null participant");
					Assert.isTrue(p.getId()!=0, "tried to found evaluations made by a participant with id zero");
					
					Collection<Evaluation> res;
					
					res = this.evaluationRepository.findEvaluationsByParticipant(p.getId());
					//Assert.isNull(res,"found evaluation collection is null");
					
					return res;
				}
				
			private void checkPrincipal(Evaluation evaluation, String message){
				Participant principal = participantService.findByPrincipal();
				Assert.isTrue(principal.equals(evaluation.getParticipant()),message);
			}


	// Hacking protection related methods -----------------------------------------------
	public Boolean itsHacked(Evaluation evaluation){
		Boolean res = true;
		if(evaluation.getId()!=0){
		Evaluation persistedOne = evaluationRepository.findOne(evaluation.getId());
		
		if(evaluation.getParticipant()==null || persistedOne.getParticipant().equals(evaluation.getParticipant()))
			if(evaluation.getRoute()==null || persistedOne.getRoute().equals(evaluation.getRoute()))
				res = false;
		}
		else{
			res=false;
		}
		
		return res;
	}
	
//	// Form object related methods ---------------------------------------
//	public EvaluationForm getFormObject(Evaluation evaluation){
//		EvaluationForm res;
//		
//		res = new EvaluationForm();
//		res.setAssessment(evaluation.getAssessment());
//		res.setEntityId(evaluation.getId());
//		
//		return res;
//	}
//	
//	public Evaluation reconstruct(EvaluationForm evaluationForm){
//		Evaluation res;
//		
//		res = evaluationRepository.findOne(evaluationForm.getEntityId());
//		res.setAssessment(evaluationForm.getAssessment());
//		
//		return res;
//	}
	
}
